import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Sprite, Graphics, Text, useTick, Container } from '@inlet/react-pixi';
import * as PIXI from 'pixi.js'
function SpinnerCountDown({
    position = [0, 0],
    innerColor = 0x363D6F,
    outerStartColor = 0x329FEF,
    outerEndColor = 0x7CFAE5,
    innerRadius = 58,
    outerRadius = 65,
    tips = '',
    maxTime = 10,
    nowTime,
    showTime = true,
    timeTextStyle = new PIXI.TextStyle({
        fontFamily: 'Roboto-Medium, Roboto',
        fontSize: 20,
        fontWeight: 'bold',
        fill: ['#ffffff'],
    }),
    tipsTextStyle = new PIXI.TextStyle({
        fontSize: 12,
        fill: ['#CCD3FF']
    }),
    showLoading = false,
    loadingText = '',
    loadingTextStyle = new PIXI.TextStyle({
        fontSize: 14,
        fill: ['#CCD3FF']
    }),
}) {
    position = position.map(item => item + outerRadius)
    // 使用canvas画渐变套进去
    const gradTexture = useMemo(
        () => gradient('#' + outerEndColor.toString(16), '#' + outerStartColor.toString(16), outerRadius * 2, outerRadius * 2),
        []
    )
    const [circleTimeOutPI, setCircleTimeOutPI] = useState(-Math.PI / 2 + (2 * Math.PI / maxTime * (maxTime - (nowTime ?? maxTime))))
    const [time, setTime] = useState((maxTime - (nowTime ?? maxTime)) * 60)
    const [timeText, setTimeText] = useState(maxTime)
    const [scale, setScale] = useState(0)
    const innerDraw = useCallback(
        (g) => {
            g.beginFill(innerColor)
            g.drawTorus(position[0],position[1],innerRadius,outerRadius)
            g.endFill();
        },
        [],
    )
    const Mask = useMemo(
        () => new PIXI.Graphics()
            .beginFill(outerStartColor)
            .drawTorus(position[0],position[1],innerRadius,outerRadius,circleTimeOutPI, Math.PI + Math.PI / 2)
            .endFill(),
        [],
    )
    useEffect(() => {
        if (showLoading) {
            setCircleTimeOutPI(-Math.PI / 2)
        } else {
            setCircleTimeOutPI(-Math.PI / 2 + (2 * Math.PI / maxTime * (maxTime - (nowTime ?? maxTime))))
            setTime((maxTime - (nowTime ?? maxTime)) * 60)
        }
    }, [showLoading])
    useTick(delta => {
        setScale(scale => {
            if (scale < 1) {
                scale += 1 / 60 / 0.4
            } else {
                scale = 1
            }
            return scale
        })
        if (showLoading) {
            setCircleTimeOutPI(newV => {
                let circleTimeOutPI = newV + 2 * Math.PI / 60 / 3
                if (circleTimeOutPI >= Math.PI + Math.PI / 2) {
                    circleTimeOutPI = -Math.PI / 2
                }
                Mask.clear()
                    .beginFill(outerStartColor)
                    .drawTorus(position[0],position[1],innerRadius,outerRadius,circleTimeOutPI, circleTimeOutPI + Math.PI / 3)
                    .endFill(outerEndColor);
                return circleTimeOutPI
            })
        } else {
            setCircleTimeOutPI(newV => {
                let circleTimeOutPI = newV + 2 * Math.PI / 60 / maxTime
                if (circleTimeOutPI >= Math.PI + Math.PI / 2) {
                    circleTimeOutPI = Math.PI + Math.PI / 2
                }
                Mask.clear()
                    .beginFill(outerStartColor)
                    .drawTorus(position[0],position[1],innerRadius,outerRadius,circleTimeOutPI, Math.PI + Math.PI / 2)
                    .endFill(outerEndColor);
                return circleTimeOutPI
            })
            setTime(t => {
                if (t >= 60 * maxTime) {
                    t = 60 * maxTime;
                }
                if (time % 60 === 0) {
                    setTimeText((maxTime - t / 60).toString().padStart(2, '0'))
                }
                return t + 1
            })
        }
    })
    return (
        <Container
            x={position[0] * (1 - scale)}
            y={position[1] * (1 - scale)}
            scale={scale}
        >
            <Graphics
                draw={innerDraw}
            />
            {
                scale === 1 && <Sprite
                    texture={gradTexture}
                    width={outerRadius * 2}
                    height={outerRadius * 2}
                    x={position[0] - outerRadius}
                    y={position[1] - outerRadius}
                    mask={Mask}
                />
            }
            {
                showLoading
                ?
                <Text
                    text={loadingText}
                    anchor={[0.5, -1]}
                    x={position[0]}
                    y={position[1]}
                    style={loadingTextStyle}
                />
                :
                <>
                    <Text
                        text={tips}
                        anchor={[0.5, -2]}
                        x={position[0]}
                        y={position[1]}
                        style={tipsTextStyle}
                    />
                    <Text
                        visible={showTime}
                        text={`${timeText} s`}
                        anchor={[0.5, -0.1]}
                        x={position[0]}
                        y={position[1]}
                        style={timeTextStyle}
                    />
                </>
            }
        </Container>
    )
}

// fromColor起始颜色，toColor终点颜色， width绘制图形的宽度， height绘制图形的高度
function gradient(fromColor, toColor, width, height) {
    const c = document.createElement("canvas");
    c.width = width;
    c.height = height;
    const ctx = c.getContext("2d");
    const grd = ctx.createLinearGradient(0,0,width, 0);
    grd.addColorStop(0, fromColor);
    grd.addColorStop(1, toColor);
    ctx.fillStyle = grd;
    ctx.fillRect(0,0,width,height);
    return PIXI.Texture.from(c)
}

export default SpinnerCountDown
